'''
Created on Oct 16, 2012
Refactored on Jul 4, 2013

@author: Nils Amiet
'''

import time
import math
from contextlib import contextmanager

@contextmanager
def timer():
    '''Context manager used to wrap some code with a timer and print the execution time at the end'''
    timer = Timer()
    timer.start()
    yield
    timer.stop()
    print(timer)
    

class Timer:
    '''Class used to measure the execution time of some code'''
    
    MILLIS_PER_SECOND = 1000
    MILLIS_PER_MINUTE = MILLIS_PER_SECOND * 60
    MILLIS_PER_HOUR = MILLIS_PER_MINUTE * 60
    MILLIS_PER_DAY = MILLIS_PER_HOUR * 24
    
    def __init__(self):
        self.startMillis = 0
        self.endMillis = 0
        self.totalTimeMillis = 0
        
    def start(self):
        self.startMillis = int(time.time() * self.MILLIS_PER_SECOND)
        
    def stop(self):
        self.endMillis = int(time.time() * self.MILLIS_PER_SECOND)
        self.totalTimeMillis = self.endMillis - self.startMillis
        
    def __repr__(self):
        tempTime = self.totalTimeMillis
        
        days = math.floor(tempTime / self.MILLIS_PER_DAY)
        tempTime -= days * self.MILLIS_PER_DAY
        
        hours = math.floor(tempTime / self.MILLIS_PER_HOUR)
        tempTime -= hours * self.MILLIS_PER_HOUR
        
        minutes = math.floor(tempTime / self.MILLIS_PER_MINUTE)
        tempTime -= minutes * self.MILLIS_PER_MINUTE
        
        seconds = math.floor(tempTime / self.MILLIS_PER_SECOND)
        tempTime -= seconds * self.MILLIS_PER_SECOND
        
        millis = tempTime
        
        timeString = "%s days, %s hours, %s minutes, %s seconds, %s millis."
        timeString %= (days, hours, minutes, seconds, millis)
                
        return timeString